// src/services/api.ts
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import AsyncStorage from '@react-native-async-storage/async-storage';
import Toast from 'react-native-toast-message';
import { store } from '../store/store';
import { logout } from '../store/slices/authSlice';
import { API_BASE_URL, API_TIMEOUT } from '../utils/constants';
import { Platform } from 'react-native';
import authService from "./authService.ts";

// API响应格式
interface ApiResponse<T = any> {
  code: number;
  message: string;
  data: T;
  timestamp?: number;
}

class ApiClient {
  private client: AxiosInstance;
  private refreshTokenPromise: Promise<string> | null = null;

  constructor() {
    this.client = axios.create({
      baseURL: API_BASE_URL,
      timeout: API_TIMEOUT,
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      },
    });

    this.setupInterceptors();
  }

  private setupInterceptors() {
    // 请求拦截器
    this.client.interceptors.request.use(
      async (config) => {
        // 添加认证token
        const token = await AsyncStorage.getItem('token');
        if (token) {
          config.headers.Authorization = `Bearer ${token}`;
        }

        // 添加设备信息
        config.headers['X-Device-Type'] = Platform.OS;
        config.headers['X-App-Version'] = '1.0.0';

        // 添加语言
        config.headers['Accept-Language'] =
          (await AsyncStorage.getItem('language')) || 'zh-CN';

        console.log(`[API] ${config.method?.toUpperCase()} ${config.url}`, config.data);

        return config;
      },
      (error) => {
        console.error('[API] Request error:', error);
        return Promise.reject(error);
      }
    );

    // 响应拦截器
    this.client.interceptors.response.use(
      (response: AxiosResponse<ApiResponse>) => {
        console.log(`[API] Response:`, response.data);

        // 处理业务错误
        if (response.data.code !== 200) {
          const error = new Error(response.data.message);
          (error as any).code = response.data.code;
          return Promise.reject(error);
        }

        return {
          ...response,
          data: response.data.data,
        };
      },
      async (error) => {
        console.error('[API] Response error:', error);

        if (!error.response) {
          // 网络错误
          Toast.show({
            type: 'error',
            text1: '网络错误',
            text2: '请检查网络连接',
          });
          return Promise.reject(error);
        }

        const { status, data } = error.response;

        switch (status) {
          case 401:
            // Token过期，尝试刷新
            return this.handleTokenExpired(error);

          case 403:
            Toast.show({
              type: 'error',
              text1: '权限不足',
              text2: data?.message || '您没有权限执行此操作',
            });
            break;

          case 404:
            Toast.show({
              type: 'error',
              text1: '请求失败',
              text2: '请求的资源不存在',
            });
            break;

          case 429:
            Toast.show({
              type: 'error',
              text1: '请求过于频繁',
              text2: '请稍后再试',
            });
            break;

          case 500:
          case 502:
          case 503:
            Toast.show({
              type: 'error',
              text1: '服务器错误',
              text2: '请稍后重试',
            });
            break;

          default:
            Toast.show({
              type: 'error',
              text1: '请求失败',
              text2: data?.message || `错误代码: ${status}`,
            });
        }

        return Promise.reject(error);
      }
    );
  }

  private async handleTokenExpired(error: any): Promise<any> {
    const originalRequest = error.config;

    // 如果已经在刷新token，等待刷新完成
    if (this.refreshTokenPromise) {
      const token = await this.refreshTokenPromise;
      originalRequest.headers.Authorization = `Bearer ${token}`;
      return this.client(originalRequest);
    }

    // 开始刷新token
    this.refreshTokenPromise = this.refreshToken();

    try {
      const token = await this.refreshTokenPromise;
      originalRequest.headers.Authorization = `Bearer ${token}`;
      return this.client(originalRequest);
    } catch (refreshError) {
      // 刷新失败，退出登录
      store.dispatch(logout());
      return Promise.reject(refreshError);
    } finally {
      this.refreshTokenPromise = null;
    }
  }

  private async refreshToken(): Promise<string> {
    try {
      const refreshToken = await AsyncStorage.getItem('refreshToken');
      if (!refreshToken) {
        throw new Error('No refresh token');
      }

      const response = await this.post('/auth/user/refresh-token', {
        refreshToken,
      });

      const { token, refreshToken: newRefreshToken } = response.data;

      await AsyncStorage.setItem('token', token);
      if (newRefreshToken) {
        await AsyncStorage.setItem('refreshToken', newRefreshToken);
      }

      return token;
    } catch (error) {
      throw error;
    }
  }

  // HTTP方法
  async get<T = any>(url: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
    return this.client.get(url, config);
  }

  async post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
    return this.client.post(url, data, config);
  }

  async put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
    return this.client.put(url, data, config);
  }

  async delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
    return this.client.delete(url, config);
  }

  // 文件上传
  async upload<T = any>(url: string, formData: FormData, onProgress?: (progress: number) => void): Promise<ApiResponse<T>> {
    return this.client.post(url, formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
      onUploadProgress: (progressEvent) => {
        if (onProgress && progressEvent.total) {
          const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total);
          onProgress(progress);
        }
      },
    });
  }

  // 文件下载
  async download(url: string, onProgress?: (progress: number) => void): Promise<Blob> {
    const response = await this.client.get(url, {
      responseType: 'blob',
      onDownloadProgress: (progressEvent) => {
        if (onProgress && progressEvent.total) {
          const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total);
          onProgress(progress);
        }
      },
    });

    return response.data;
  }
}

export default new ApiClient();